<template>
  <view class="chat-container">
    <!-- 顶部导航栏 -->
    <view class="top-bar">
      <view class="top-bar-title">AI助手</view>
      <view class="top-bar-right" @click="goToSettings">
        <text class="settings-icon">⚙️</text>
      </view>
    </view>
    
    <!-- 消息列表 -->
    <scroll-view 
      class="message-list" 
      scroll-y 
      :scroll-top="scrollTop"
      scroll-with-animation
    >
      <view v-if="messages.length === 0" class="empty-message">
        <text class="empty-text">👋 你好！我是AI助手，有什么可以帮你的吗？</text>
      </view>
      
      <view 
        v-for="(msg, index) in messages" 
        :key="index" 
        class="message-item"
        :class="msg.role === 'user' ? 'user-message' : 'ai-message'"
      >
        <!-- 时间显示在上方 -->
        <text v-if="msg.audioUrl" class="voice-time">{{ msg.time }}</text>
        
        <view class="message-content">
          <view class="avatar">
            <image 
              v-if="msg.role === 'user'" 
              :src="userAvatar" 
              class="avatar-img"
              mode="aspectFill"
              @error="handleAvatarError"
            />
            <!-- AI头像：显示“宠物”文字 -->
            <view v-else class="avatar-text">
              <text class="pet-text">宠物</text>
            </view>
          </view>
          
          <!-- 如果有音频URL，只显示绿色气泡，不要外层背景 -->
          <view 
            v-if="msg.audioUrl" 
            class="voice-message" 
            :class="'voice-duration-' + Math.min(msg.duration || 1, 15)"
            @click="playVoice(msg.audioUrl, index)"
          >
            <text class="voice-duration">{{ msg.duration || 7 }}''</text>
          </view>
          
          <!-- 普通文本消息，保留原样式 -->
          <view v-else class="text-bubble">
            <text class="message-text">{{ msg.content }}</text>
            <text class="message-time">{{ msg.time }}</text>
          </view>
        </view>
      </view>
      
      <!-- 加载中提示 -->
      <view v-if="isLoading" class="message-item ai-message">
        <view class="message-content">
          <view class="avatar">
            <!-- AI头像：显示“宠物”文字 -->
            <view class="avatar-text">
              <text class="pet-text">宠物</text>
            </view>
          </view>
          <view class="text-bubble loading-bubble">
            <view class="loading-spinner">
              <view class="spinner"></view>
            </view>
            <text class="loading-text">思考中</text>
            <view class="loading-dots">
              <text class="dot">.</text>
              <text class="dot">.</text>
              <text class="dot">.</text>
              <text class="dot">.</text>
              <text class="dot">.</text>
              <text class="dot">.</text>
            </view>
          </view>
        </view>
      </view>
    </scroll-view>

    <!-- 输入区域 -->
    <view class="input-container">
      <view class="input-wrapper">
        <!-- 语音按钮 - 微信风格 -->
        <view 
          class="voice-btn-wechat"
          :class="{ 'voice-btn-pressed': isRecording }"
          @touchstart="startRecording"
          @touchmove="onTouchMove"
          @touchend="stopRecording"
          @touchcancel="cancelRecording"
        >
          <text class="voice-btn-text">{{ isRecording ? '松开 发送' : '按住 说话' }}</text>
        </view>
        
        <!-- 文本输入框 - 已注释，后续可能启用 -->
        <!-- <input 
          class="text-input" 
          v-model="inputText"
          :adjust-position="true"
          confirm-type="send"
          @confirm="sendMessage"
          placeholder="输入消息..."
          :disabled="isLoading"
        /> -->
        
        <!-- 发送按钮 - 已注释，后续可能启用 -->
        <!-- <view 
          class="send-btn" 
          :class="{ 'send-btn-active': inputText.trim() }"
          @click="sendMessage"
        >
          <text class="send-text">发送</text>
        </view> -->
      </view>
      
      <!-- 录音提示 -->
      <view v-if="isRecording" class="recording-mask">
        <!-- 录音气泡弹窗 -->
        <view class="recording-popup" :class="{ 'recording-cancel': isCancelMode }">
          <view class="recording-wave-container">
            <!-- 波形动画 -->
            <view class="wave-bar wave-bar-1"></view>
            <view class="wave-bar wave-bar-2"></view>
            <view class="wave-bar wave-bar-3"></view>
            <view class="wave-bar wave-bar-4"></view>
            <view class="wave-bar wave-bar-5"></view>
            <view class="wave-bar wave-bar-6"></view>
            <view class="wave-bar wave-bar-7"></view>
            <view class="wave-bar wave-bar-8"></view>
            <view class="wave-bar wave-bar-9"></view>
            <view class="wave-bar wave-bar-10"></view>
            <view class="wave-bar wave-bar-11"></view>
            <view class="wave-bar wave-bar-12"></view>
            <view class="wave-bar wave-bar-13"></view>
            <view class="wave-bar wave-bar-14"></view>
            <view class="wave-bar wave-bar-15"></view>
            <view class="wave-bar wave-bar-16"></view>
            <view class="wave-bar wave-bar-17"></view>
            <view class="wave-bar wave-bar-18"></view>
            <view class="wave-bar wave-bar-19"></view>
            <view class="wave-bar wave-bar-20"></view>
          </view>
        </view>
        
        <!-- 底部操作提示 -->
        <view class="recording-actions">
          <view class="action-item cancel-action" :class="{ 'cancel-active': isCancelMode }">
            <text class="action-text">松开手指，取消发送</text>
          </view>
        </view>
        
        <!-- 松开发送提示 -->
        <view v-if="!isCancelMode" class="release-tip">
          <text class="release-text">松开 发送</text>
        </view>
      </view>
    </view>
  </view>
</template> 

<script>
import { uploadToOSS } from '@/utils/ossUpload';

const defaultAvatar = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0';

export default {
  data() {
    return {
      // 测试模式配置：true=只测试前端效果，false=正常与后端交互
      testMode: false,
      
      messages: [],
      inputText: '',
      isLoading: false,
      scrollTop: 0,
      userAvatar: defaultAvatar,
      isRecording: false,
      recorderManager: null,
      recordStartTime: 0,
      tempFilePath: '',
      audioContext: null, // 音频播放器
      currentPlayingIndex: -1, // 当前播放的消息索引
      
      // 录音相关
      touchStartY: 0, // 触摸开始位置
      isCancelMode: false, // 是否为取消模式
      shouldCancelRecording: false, // 是否应该取消录音（标记）
    };
  },
  onLoad() {
    // 获取用户头像，并验证是否为有效的远程图片
    const avatarUrl = uni.getStorageSync('avatarUrl');
    if (avatarUrl && (avatarUrl.startsWith('http://') || avatarUrl.startsWith('https://'))) {
      this.userAvatar = avatarUrl;
    } else {
      // 如果是本地临时文件或无效路径，使用默认头像
      this.userAvatar = defaultAvatar;
    }
    
    // 初始化录音管理器
    this.initRecorder();
    
    // 初始化音频播放器
    this.initAudioPlayer();
    
    // 检查登录状态
    this.checkLogin();
    
    // 开发环境提示：检查是否需要配置域名白名单
    // #ifdef MP-WEIXIN
    if (process.env.NODE_ENV === 'development') {
      console.warn('开发提示：请确保在微信公众平台配置了 request 合法域名: https://dashscope.aliyuncs.com');
    }
    // #endif
  },
  onUnload() {
    // 页面卸载时，停止音频播放
    if (this.audioContext) {
      this.audioContext.stop();
      this.audioContext.destroy();
    }
  },
  methods: {
    // 处理头像加载错误
    handleAvatarError(e) {
      console.error('头像加载失败', e);
      // 回退到默认头像
      this.userAvatar = defaultAvatar;
      // 更新存储
      uni.setStorageSync('avatarUrl', defaultAvatar);
    },
    
    checkLogin() {
      const isLogin = uni.getStorageSync('isLogin');
      if (!isLogin) {
        uni.showModal({
          title: '提示',
          content: '请先登录才能使用AI助手',
          showCancel: false,
          success: () => {
            uni.reLaunch({
              url: '/pages/login/index'
            });
          }
        });
      }
    },
    
    // 初始化音频播放器
    initAudioPlayer() {
      this.audioContext = uni.createInnerAudioContext();
      
      this.audioContext.onPlay(() => {
        console.log('🔊 开始播放语音');
      });
      
      this.audioContext.onEnded(() => {
        console.log('✅ 语音播放结束');
        this.currentPlayingIndex = -1;
      });
      
      this.audioContext.onError((err) => {
        console.error('❌ 音频播放错误:', err);
        this.currentPlayingIndex = -1;
        uni.showToast({
          title: '播放失败',
          icon: 'none'
        });
      });
    },
    
    // 播放语音
    playVoice(audioUrl, index) {
      console.log('🎵 准备播放语音:', audioUrl);
      
      // 测试模式：只显示提示，不真正播放
      if (this.testMode) {
        console.log('🚧 测试模式：模拟播放语音');
        
        // 切换播放状态
        if (this.currentPlayingIndex === index) {
          this.currentPlayingIndex = -1;
          uni.showToast({
            title: '停止播放',
            icon: 'none'
          });
        } else {
          this.currentPlayingIndex = index;
          uni.showToast({
            title: '开始播放',
            icon: 'none'
          });
          
          // 3秒后自动停止
          setTimeout(() => {
            this.currentPlayingIndex = -1;
          }, 3000);
        }
        return;
      }
      
      if (!audioUrl) {
        uni.showToast({
          title: '音频地址无效',
          icon: 'none'
        });
        return;
      }
      
      // 如果当前正在播放该消息，则停止播放
      if (this.currentPlayingIndex === index) {
        this.audioContext.stop();
        this.currentPlayingIndex = -1;
        return;
      }
      
      // 停止之前的播放
      this.audioContext.stop();
      
      // 设置新的音频源并播放
      this.audioContext.src = audioUrl;
      this.audioContext.play();
      this.currentPlayingIndex = index;
    },
    
    // 获取音频真实时长
    getAudioDuration(audioUrl) {
      return new Promise((resolve) => {
        console.log('🎵 开始获取音频时长:', audioUrl);
        
        // 创建临时音频上下文
        const tempAudio = uni.createInnerAudioContext();
        let resolved = false; // 防止多次resolve
        
        const cleanup = (duration) => {
          if (resolved) return;
          resolved = true;
          try {
            tempAudio.stop();
            tempAudio.destroy();
          } catch (e) {
            console.warn('清理音频上下文失败:', e);
          }
          resolve(duration);
        };
        
        tempAudio.src = audioUrl;
        
        // 真机上需要设置这些属性
        tempAudio.obeyMuteSwitch = false; // 不遵循静音开关
        tempAudio.volume = 0; // 设置音量为0，不发出声音
        
        // 监听音频加载完成 - 真机上可能需要play后才能获取duration
        tempAudio.onCanplay(() => {
          console.log('🎵 音频canplay事件触发');
          
          // 延迟一下再读取duration，确保已就绪
          setTimeout(() => {
            const duration = Math.round(tempAudio.duration);
            console.log('✅ 从canplay获取音频时长:', duration, '秒');
            
            if (duration > 0) {
              cleanup(duration);
            } else {
              console.warn('⚠️ canplay事件中duration为0，尝试播放获取');
              // duration为0时，尝试播放来触发时长更新
              tempAudio.play();
            }
          }, 100);
        });
        
        // 监听播放事件 - 真机上通过play可能更可靠
        tempAudio.onPlay(() => {
          console.log('🎵 音频play事件触发');
          const duration = Math.round(tempAudio.duration);
          console.log('✅ 从play获取音频时长:', duration, '秒');
          
          if (duration > 0 && !resolved) {
            cleanup(duration);
          }
        });
        
        // 监听时长更新事件
        tempAudio.onTimeUpdate(() => {
          if (!resolved) {
            const duration = Math.round(tempAudio.duration);
            if (duration > 0) {
              console.log('✅ 从timeUpdate获取音频时长:', duration, '秒');
              cleanup(duration);
            }
          }
        });
        
        // 监听错误
        tempAudio.onError((err) => {
          console.error('❌ 获取音频时长失败:', err);
          cleanup(5); // 失败时返回默认5秒
        });
        
        // 超时处理（延长到8秒，真机网络可能较慢）
        setTimeout(() => {
          if (!resolved) {
            console.warn('⚠️ 获取音频时长超时，使用默认值5秒');
            cleanup(5);
          }
        }, 8000);
        
        // 真机上可能需要主动play来触发duration加载
        // 延迟500ms后如果还没获取到，就尝试play
        setTimeout(() => {
          if (!resolved) {
            console.log('🎵 尝试播放以获取时长...');
            try {
              tempAudio.play();
            } catch (e) {
              console.warn('播放失败:', e);
            }
          }
        }, 500);
      });
    },
    
    // 初始化录音管理器
    initRecorder() {
      this.recorderManager = uni.getRecorderManager();
      
      this.recorderManager.onStart(() => {
        console.log('开始录音');
      });
      
      this.recorderManager.onStop((res) => {
        console.log('录音结束', res);
        
        // 检查是否应该取消
        if (this.shouldCancelRecording) {
          console.log('❌ 已标记为取消，不处理录音文件');
          this.shouldCancelRecording = false; // 重置标记
          return;
        }
        
        this.tempFilePath = res.tempFilePath;
        
        // 计算录音时长（秒）
        const duration = Math.floor((Date.now() - this.recordStartTime) / 1000);
        console.log('🕒 录音时长:', duration, '秒');
        
        // 测试模式：只测试前端显示，不上传OSS
        if (this.testMode) {
          console.log('🚧 测试模式：跳过OSS上传');
          this.showTestVoiceMessage(duration);
        } else {
          this.uploadVoice(res.tempFilePath, duration);
        }
      });
      
      this.recorderManager.onError((err) => {
        console.error('录音错误', err);
        uni.showToast({
          title: '录音失败，请重试',
          icon: 'none'
        });
      });
    },
    
    // 开始录音
    startRecording(e) {
      this.isRecording = true;
      this.recordStartTime = Date.now();
      this.touchStartY = e.touches[0].clientY; // 记录触摸开始位置
      this.isCancelMode = false;
      this.shouldCancelRecording = false; // 重置取消标记
      
      // 检查录音权限
      uni.authorize({
        scope: 'scope.record',
        success: () => {
          this.recorderManager.start({
            format: 'mp3',
            sampleRate: 16000,
            numberOfChannels: 1,
            encodeBitRate: 48000
          });
        },
        fail: () => {
          this.isRecording = false;
          uni.showModal({
            title: '需要录音权限',
            content: '请在设置中开启录音权限',
            confirmText: '去设置',
            success: (res) => {
              if (res.confirm) {
                uni.openSetting();
              }
            }
          });
        }
      });
    },
    
    // 触摸移动监听（上滑取消）
    onTouchMove(e) {
      if (!this.isRecording) return;
      
      const currentY = e.touches[0].clientY;
      const moveDistance = this.touchStartY - currentY;
      
      // 上滑超过100px进入取消模式
      if (moveDistance > 100) {
        if (!this.isCancelMode) {
          this.isCancelMode = true;
          console.log('🚫 进入取消模式');
          // 可以添加震动反馈
          uni.vibrateShort();
        }
      } else {
        if (this.isCancelMode) {
          this.isCancelMode = false;
          console.log('✅ 退出取消模式');
        }
      }
    },
    
    // 停止录音
    stopRecording() {
      if (!this.isRecording) return;
      
      const duration = Date.now() - this.recordStartTime;
      
      // 如果处于取消模式，标记为取消
      if (this.isCancelMode) {
        console.log('🚫 取消录音（上滑取消）');
        this.shouldCancelRecording = true; // 设置取消标记
        this.recorderManager.stop();
        this.isRecording = false;
        this.isCancelMode = false;
        uni.showToast({
          title: '已取消录音',
          icon: 'none'
        });
        return;
      }
      
      // 录音时间太短
      if (duration < 1000) {
        uni.showToast({
          title: '录音时间太短',
          icon: 'none'
        });
        this.shouldCancelRecording = true; // 标记为取消
        this.recorderManager.stop();
        this.isRecording = false;
        return;
      }
      
      // 正常发送
      this.recorderManager.stop();
      this.isRecording = false;
    },
    
    // 取消录音
    cancelRecording() {
      if (this.isRecording) {
        console.log('🚫 取消录音');
        this.shouldCancelRecording = true; // 设置取消标记
        this.recorderManager.stop();
        this.isRecording = false;
        
        // 显示取消提示
        uni.showToast({
          title: '已取消录音',
          icon: 'none'
        });
      }
    },
    
    // 测试模式：显示测试语音消息
    showTestVoiceMessage(duration) {
      console.log('========== 测试模式：显示语音消息 ==========');
      console.log('🕒 时长:', duration, '秒');
      
      // 添加用户语音消息
      const userMessage = {
        role: 'user',
        content: '🎤 [语音消息]',
        time: this.formatTime(new Date()),
        audioUrl: 'test-audio-url', // 测试URL
        duration: duration
      };
      this.messages.push(userMessage);
      
      // 滚动到底部
      this.scrollToBottom();
      
      console.log('✅ 测试模式：用户语音消息已添加，不模拟AI回复');
    },
    
    // 上传语音并转文字
    async uploadVoice(filePath, duration) {
      console.log('========== 语音上传开始 ==========');
      console.log('📁 录音文件路径:', filePath);
      console.log('🕒 录音时长:', duration, '秒');
      
      uni.showLoading({ title: '正在上传语音...' });
      
      try {
        // 上传到阿里云OSS
        const ossUrl = await uploadToOSS(filePath, 'mp3');
        
        console.log('✅ OSS上传成功');
        console.log('🔗 OSS URL:', ossUrl);
        
        uni.hideLoading();
        
        // 使用OSS URL作为prompt调用AI，传入时长
        this.inputText = '';
        this.sendVoiceMessage(ossUrl, duration);
        
      } catch (err) {
        uni.hideLoading();
        console.error('❌ 语音上传失败:', err);
        uni.showToast({
          title: '语音上传失败',
          icon: 'none'
        });
      }
    },
    
    // 发送语音消息（使用OSS URL作为prompt）
    async sendVoiceMessage(ossUrl, duration = 0) {
      console.log('========== 发送语音消息 ==========');
      console.log('🎤 语音URL:', ossUrl);
      console.log('🕒 时长:', duration, '秒');
      
      // 添加用户消息（显示为语音）
      const userMessage = {
        role: 'user',
        content: '🎤 [语音消息]',
        time: this.formatTime(new Date()),
        audioUrl: ossUrl,
        duration: duration
      };
      this.messages.push(userMessage);
      
      // 滚动到底部
      this.scrollToBottom();
      
      // 发送请求
      this.isLoading = true;
      
      try {
        // 将OSS URL转换为数组格式的字符串：JSON.stringify([ossUrl])
        const promptArray = JSON.stringify([ossUrl]);
        console.log('📋 Prompt数组格式:', promptArray);
        
        // 调用阿里云百炼大模型API，使用数组格式的prompt
        const response = await this.callDashScopeAPI(promptArray, true);
        
        this.isLoading = false;
        
        if (response && response.output) {
          console.log('📦 完整响应数据:', JSON.stringify(response, null, 2));
          
          // 解析返回的语音URL和时长
          let audioUrl = null;
          let audioDuration = null; // 不设置默认值，等待解析
          let textContent = '播放语音回复';
          
          try {
            // 情况1: output.text 是嵌套的JSON字符串
            if (response.output.text) {
              console.log('🔍 解析output.text...');
              const textData = JSON.parse(response.output.text);
              console.log('📦 解析后的text数据:', JSON.stringify(textData, null, 2));
              
              // 检查解析后的数据中是否有output.content
              if (textData.output && textData.output.content && textData.output.content.length > 0) {
                const contentText = textData.output.content[0].text;
                console.log('📝 Content文本:', contentText);
                
                const contentObj = JSON.parse(contentText);
                console.log('📦 解析后的content对象:', JSON.stringify(contentObj, null, 2));
                
                if (contentObj.result) {
                  audioUrl = contentObj.result;
                  console.log('✅ 成功解析到语音URL:', audioUrl);
                  
                  // 尝试从多个来源获取时长
                  if (contentObj.duration) {
                    audioDuration = Math.round(parseFloat(contentObj.duration));
                    console.log('✅ 从contentObj.duration解析时长:', audioDuration, '秒');
                  } else if (contentObj.audio_duration) {
                    audioDuration = Math.round(parseFloat(contentObj.audio_duration));
                    console.log('✅ 从contentObj.audio_duration解析时长:', audioDuration, '秒');
                  } else {
                    // 尝试通过下载音频文件获取真实时长
                    console.log('⚠️ API未返回时长信息，准备获取音频真实时长...');
                    audioDuration = await this.getAudioDuration(audioUrl);
                  }
                }
              }
            }
            // 情况2: 直接在 output.content 中
            else if (response.output.content && response.output.content.length > 0) {
              console.log('🔍 直接从output.content解析...');
              const contentText = response.output.content[0].text;
              const contentObj = JSON.parse(contentText);
              
              if (contentObj.result) {
                audioUrl = contentObj.result;
                console.log('✅ 成功解析到语音URL:', audioUrl);
                
                // 尝试从多个来源获取时长
                if (contentObj.duration) {
                  audioDuration = Math.round(parseFloat(contentObj.duration));
                  console.log('✅ 从contentObj.duration解析时长:', audioDuration, '秒');
                } else if (contentObj.audio_duration) {
                  audioDuration = Math.round(parseFloat(contentObj.audio_duration));
                  console.log('✅ 从contentObj.audio_duration解析时长:', audioDuration, '秒');
                } else {
                  // 尝试通过下载音频文件获取真实时长
                  console.log('⚠️ API未返回时长信息，准备获取音频真实时长...');
                  audioDuration = await this.getAudioDuration(audioUrl);
                }
              }
            }
          } catch (parseErr) {
            console.error('❌ 解析语音URL失败:', parseErr);
            console.error('❌ 错误详情:', parseErr.message);
          }
          
          // 如果仍然没有获取到时长，使用默认值
          if (!audioDuration || audioDuration <= 0) {
            audioDuration = 5;
            console.log('⚠️ 使用默认时长:', audioDuration, '秒');
          }
          
          const aiMessage = {
            role: 'assistant',
            content: audioUrl ? '🔊 点击播放语音回复' : textContent,
            time: this.formatTime(new Date()),
            audioUrl: audioUrl, // 保存音频URL
            duration: audioDuration // 保存语音时长
          };
          
          this.messages.push(aiMessage);
          this.scrollToBottom();
          
          // 如果有语音，自动播放
          if (audioUrl) {
            console.log('🎵 准备自动播放语音...');
            setTimeout(() => {
              this.playVoice(audioUrl, this.messages.length - 1);
            }, 500);
          } else {
            console.warn('⚠️ 未找到语音URL，无法播放');
          }
        } else {
          throw new Error('回复内容为空');
        }
      } catch (err) {
        this.isLoading = false;
        console.error('发送语音消息失败:', err);
        
        // 根据错误类型显示不同的错误消息
        let errorText = '抱歉，处理语音消息时遇到了问题，请稍后重试。';
        let toastText = '处理失败';
        
        if (err.message) {
          if (err.message.includes('超时')) {
            errorText = '抱歉，处理语音消息超时了，请检查网络连接后重试。';
            toastText = '请求超时';
          } else if (err.message.includes('网络')) {
            errorText = '抱歉，网络连接失败，请检查网络设置。';
            toastText = '网络连接失败';
          }
        }
        
        // 添加错误提示消息
        const errorMessage = {
          role: 'assistant',
          content: errorText,
          time: this.formatTime(new Date())
        };
        this.messages.push(errorMessage);
        this.scrollToBottom();
        
        uni.showToast({
          title: toastText,
          icon: 'none',
          duration: 2000
        });
      }
    },
    
    // 上传文件
    uploadFile(filePath) {
      return new Promise((resolve, reject) => {
        const accessToken = uni.getStorageSync('accessToken');
        
        uni.uploadFile({
          url: this.$http.config.baseURL + '/v1/upload',
          filePath: filePath,
          name: 'file',
          header: {
            'Authorization': `Bearer ${accessToken}`
          },
          success: (res) => {
            try {
              const data = JSON.parse(res.data);
              if (data.code === 200) {
                resolve(data.data);
              } else {
                reject(new Error(data.msg || '上传失败'));
              }
            } catch (e) {
              reject(e);
            }
          },
          fail: reject
        });
      });
    },
    
    // 发送消息 - 已注释，后续可能启用
    /* async sendMessage() {
      const text = this.inputText.trim();
      if (!text || this.isLoading) return;
      
      // 添加用户消息
      const userMessage = {
        role: 'user',
        content: text,
        time: this.formatTime(new Date())
      };
      this.messages.push(userMessage);
      
      // 清空输入框
      this.inputText = '';
      
      // 滚动到底部
      this.scrollToBottom();
      
      // 发送请求
      this.isLoading = true;
      
      try {
        // 调用阿里云百炼大模型API
        const response = await this.callDashScopeAPI(text, false);
        
        this.isLoading = false;
        
        console.log('📦 文字消息响应:', JSON.stringify(response, null, 2));
        
        // 处理文字回复
        let responseText = '';
        
        if (response.output && response.output.text) {
          responseText = response.output.text;
        } else if (response.output && response.output.choices && response.output.choices.length > 0) {
          responseText = response.output.choices[0].message.content;
        } else if (response.output && response.output.content && response.output.content.length > 0) {
          // 如果返回的是content格式，尝试获取text
          responseText = response.output.content[0].text;
        }
        
        if (responseText) {
          const aiMessage = {
            role: 'assistant',
            content: responseText,
            time: this.formatTime(new Date())
          };
          this.messages.push(aiMessage);
          this.scrollToBottom();
        } else {
          throw new Error('回复内容为空');
        }
      } catch (err) {
        this.isLoading = false;
        console.error('发送消息失败详情:', err);
        
        // 根据错误类型显示不同的错误消息
        let errorText = '抱歉，我遇到了一些问题，请稍后重试。';
        let toastText = '发送失败，请重试';
        
        if (err.message) {
          if (err.message.includes('超时')) {
            errorText = '抱歉，网络请求超时了，请检查网络连接后重试。';
            toastText = '请求超时';
          } else if (err.message.includes('网络')) {
            errorText = '抱歉，网络连接失败，请检查网络设置。';
            toastText = '网络连接失败';
          } else if (err.message.includes('格式')) {
            errorText = '抱歉，AI响应格式异常，请稍后重试。';
            toastText = '响应格式错误';
          }
        }
        
        // 添加错误提示消息
        const errorMessage = {
          role: 'assistant',
          content: errorText,
          time: this.formatTime(new Date())
        };
        this.messages.push(errorMessage);
        this.scrollToBottom();
        
        uni.showToast({
          title: toastText,
          icon: 'none',
          duration: 2000
        });
      }
    }, */
    
    // 调用阿里云百炼大模型API
    callDashScopeAPI(prompt, isVoice = false, retryCount = 0) {
      const maxRetries = 1; // 最大重试次数
      
      return new Promise((resolve, reject) => {
        // 如果是语音消息，prompt已经是数组格式的字符串，直接使用
        // 如果是文字消息，prompt是普通字符串
        const requestData = {
          input: {
            prompt: isVoice ? prompt : prompt  // 语音消息时prompt已经是JSON.stringify([…])格式
          },
          parameters: {
            result_format: 'message' // 明确指定返回格式
          }
        };
        
        const startTime = Date.now();
        
        console.log('========== API请求详情 ==========');
        console.log('🚀 重试次数:', retryCount + '/' + maxRetries);
        console.log('🎤 是否语音消息:', isVoice);
        console.log('📝 Prompt类型:', typeof prompt);
        console.log('📝 Prompt内容:', prompt);
        console.log('⏰ 开始时间:', new Date(startTime).toLocaleTimeString());
        console.log('📦 请求数据:', JSON.stringify(requestData, null, 2));
        console.log('================================');
        
        uni.request({
          url: 'https://dashscope.aliyuncs.com/api/v1/apps/b64e5c2aa2b24ad6bb20365253b89811/completion',
          method: 'POST',
          timeout: 120000, // 120秒超时
          dataType: 'json',
          responseType: 'text',
          header: {
            'Authorization': 'Bearer sk-4756f890949f477db091b01bc31ae26d',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          },
          data: requestData,
          success: (res) => {
            const duration = Date.now() - startTime;
            console.log('========== API响应成功 ==========');
            console.log('✅ 状态码:', res.statusCode);
            console.log('⏱️ 耗时:', duration + 'ms');
            console.log('📦 响应类型:', typeof res.data);
            
            try {
              let responseData = res.data;
              
              // 如果是字符串，尝试解析为JSON
              if (typeof responseData === 'string') {
                console.log('🔄 解析字符串为JSON...');
                responseData = JSON.parse(responseData);
              }
              
              console.log('📦 响应数据:', JSON.stringify(responseData, null, 2));
              console.log('================================');
              
              if (res.statusCode === 200 && responseData) {
                // 检查响应数据结构
                if (responseData.output && responseData.output.text) {
                  console.log('✅ 成功获取AI回复:', responseData.output.text);
                  resolve(responseData);
                } else if (responseData.output && responseData.output.choices && responseData.output.choices.length > 0) {
                  // 处理message格式
                  const text = responseData.output.choices[0].message.content;
                  console.log('✅ 成功获取AI回复(message格式):', text);
                  resolve({
                    output: {
                      text: text
                    }
                  });
                } else if (responseData.output && responseData.output.content && responseData.output.content.length > 0) {
                  // 处理content格式（语音回复）
                  console.log('✅ 成功获取AI回复(content格式)');
                  // 直接返回原始数据，让sendVoiceMessage处理
                  resolve(responseData);
                } else if (responseData.code) {
                  console.error('❌ API返回错误码:', responseData.code, '错误信息:', responseData.message);
                  reject(new Error(`API错误: ${responseData.message || responseData.code}`));
                } else {
                  console.error('❌ 响应数据格式异常:', JSON.stringify(responseData, null, 2));
                  reject(new Error('响应数据格式不正确'));
                }
              } else {
                console.error('❌ 状态码异常:', res.statusCode);
                reject(new Error(`状态码异常: ${res.statusCode}`));
              }
            } catch (parseError) {
              console.error('❌ JSON解析错误:', parseError);
              console.error('原始数据:', res.data);
              reject(new Error('响应数据解析失败'));
            }
          },
          fail: (err) => {
            const duration = Date.now() - startTime;
            console.error('========== API请求失败 ==========');
            console.error('❌ 错误信息:', err.errMsg);
            console.error('⏱️ 失败耗时:', duration + 'ms');
            console.error('📊 当前状态 - 重试次数:', retryCount, '/', maxRetries);
            console.error('================================');
            
            // 如果是超时且还有重试机会
            if (err.errMsg && err.errMsg.includes('timeout') && retryCount < maxRetries) {
              console.log(`🔄 检测到超时，2秒后进行第 ${retryCount + 2} 次尝试...`);
              setTimeout(() => {
                this.callDashScopeAPI(prompt, isVoice, retryCount + 1)
                  .then(resolve)
                  .catch(reject);
              }, 2000);
            } else {
              // 不再重试，返回错误
              if (err.errMsg && err.errMsg.includes('timeout')) {
                reject(new Error(`请求超时（已等待${duration/1000}秒），请检查：\n1. 网络连接是否稳定\n2. 微信开发者工具是否关闭了域名校验`));
              } else if (err.errMsg && err.errMsg.includes('ssl')) {
                reject(new Error('SSL证书错误，请检查系统时间是否正确'));
              } else {
                reject(new Error(`网络请求失败: ${err.errMsg}`));
              }
            }
          }
        });
      });
    },
    
    // 滚动到底部
    scrollToBottom() {
      this.$nextTick(() => {
        this.scrollTop = 99999;
      });
    },
    
    // 格式化时间
    formatTime(date) {
      const hours = date.getHours().toString().padStart(2, '0');
      const minutes = date.getMinutes().toString().padStart(2, '0');
      return `${hours}:${minutes}`;
    },
    
    // 跳转到设置页面
    goToSettings() {
      uni.navigateTo({
        url: '/pages/settings/index'
      });
    }
  }
};
</script>

<style lang="less" scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f5f5;
}

.top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 30rpx;
  background-color: #FFF27C;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  
  .top-bar-title {
    font-size: 36rpx;
    font-weight: 600;
    color: #333;
  }
  
  .top-bar-right {
    padding: 10rpx;
    
    .settings-icon {
      font-size: 48rpx;
    }
  }
}

.message-list {
  flex: 1;
  padding: 20rpx;
  overflow-y: auto;
}

.empty-message {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 200rpx 40rpx;
  
  .empty-text {
    font-size: 28rpx;
    color: #999;
    text-align: center;
  }
}

.message-item {
  margin-bottom: 30rpx;
  display: flex;
  flex-direction: column;
  
  &.user-message {
    align-items: flex-end;
    
    .voice-time {
      align-self: flex-end;
      margin-right: 100rpx;
    }
    
    .message-content {
      flex-direction: row-reverse;
      
      .text-bubble {
        background-color: #FFF27C;
        margin-right: 20rpx;
      }
      
      // 用户语音消息：增加头像与气泡的间距
      .voice-message {
        margin-right: 20rpx;
      }
    }
  }
  
  &.ai-message {
    align-items: flex-start;
    
    .voice-time {
      align-self: flex-start;
      margin-left: 100rpx;
    }
    
    .message-content {
      flex-direction: row;
      
      .text-bubble {
        background-color: #fff;
        margin-left: 20rpx;
      }
      
      // AI语音消息：增加头像与气泡的间距
      .voice-message {
        margin-left: 20rpx;
      }
    }
  }
}

// 语音消息时间显示
.voice-time {
  font-size: 24rpx;
  color: #999;
  margin-bottom: 10rpx;
}

.message-content {
  display: flex;
  align-items: flex-start;
}

.avatar {
  width: 80rpx;
  height: 80rpx;
  flex-shrink: 0;
  
  .avatar-img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
  }
}

// AI头像文字样式
.avatar-text {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  
  .pet-text {
    font-size: 26rpx;
    color: #333;
    font-weight: 600;
    letter-spacing: 2rpx;
  }
}

.text-bubble {
  max-width: 500rpx;
  padding: 20rpx 24rpx;
  border-radius: 16rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  
  .message-text {
    font-size: 28rpx;
    line-height: 40rpx;
    color: #333;
    word-wrap: break-word;
  }
  
  .message-time {
    display: block;
    margin-top: 10rpx;
    font-size: 20rpx;
    color: #999;
  }
  
  .loading-text {
    font-size: 28rpx;
    color: #666;
  }
  
  &.loading-bubble {
    display: flex;
    align-items: center;
    gap: 16rpx;
    padding: 24rpx 28rpx;
  }
}

// 音频消息样式 - 微信风格
.voice-message {
  min-width: 120rpx;
  max-width: 300rpx;
  height: 80rpx;
  background: linear-gradient(135deg, #95EC69 0%, #7FD65C 100%);
  border-radius: 8rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 24rpx;
  cursor: pointer;
  
  .voice-duration {
    font-size: 28rpx;
    color: #000000;
    font-weight: 500;
  }
  
  &:active {
    opacity: 0.9;
  }
}

// 不同时长的宽度（每秒+20rpx）
.voice-duration-1 { width: 140rpx; }
.voice-duration-2 { width: 160rpx; }
.voice-duration-3 { width: 180rpx; }
.voice-duration-4 { width: 200rpx; }
.voice-duration-5 { width: 220rpx; }
.voice-duration-6 { width: 240rpx; }
.voice-duration-7 { width: 260rpx; }
.voice-duration-8 { width: 280rpx; }
.voice-duration-9 { width: 300rpx; }
.voice-duration-10 { width: 300rpx; }
.voice-duration-11 { width: 300rpx; }
.voice-duration-12 { width: 300rpx; }
.voice-duration-13 { width: 300rpx; }
.voice-duration-14 { width: 300rpx; }
.voice-duration-15 { width: 300rpx; }

// Loading spinner animation
.loading-spinner {
  display: flex;
  align-items: center;
  justify-content: center;
  
  .spinner {
    width: 32rpx;
    height: 32rpx;
    border: 3rpx solid #f3f3f3;
    border-top: 3rpx solid #FFF27C;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-dots {
  display: inline-flex;
  align-items: center;
  margin-left: 4rpx;
  
  .dot {
    font-size: 28rpx;
    color: #666;
    animation: blink 1.4s infinite;
    
    &:nth-child(1) { animation-delay: 0s; }
    &:nth-child(2) { animation-delay: 0.2s; }
    &:nth-child(3) { animation-delay: 0.4s; }
    &:nth-child(4) { animation-delay: 0.6s; }
    &:nth-child(5) { animation-delay: 0.8s; }
    &:nth-child(6) { animation-delay: 1s; }
  }
}

@keyframes blink {
  0%, 100% { opacity: 0.2; }
  50% { opacity: 1; }
}

.input-container {
  background-color: #fff;
  border-top: 1rpx solid #e5e5e5;
}

.input-wrapper {
  display: flex;
  align-items: center;
  padding: 20rpx;
  gap: 20rpx;
}

// 微信风格语音按钮
.voice-btn-wechat {
  flex: 1;
  height: 80rpx;
  background-color: #ffffff;
  border: 1rpx solid #d9d9d9;
  border-radius: 8rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  
  .voice-btn-text {
    font-size: 30rpx;
    color: #000000;
    font-weight: 400;
  }
  
  &.voice-btn-pressed {
    background-color: #d9d9d9;
  }
  
  &:active {
    background-color: #d9d9d9;
  }
}

.text-input {
  flex: 1;
  height: 80rpx;
  padding: 0 24rpx;
  background-color: #f5f5f5;
  border-radius: 40rpx;
  font-size: 28rpx;
}

.send-btn {
  padding: 20rpx 32rpx;
  background-color: #e5e5e5;
  border-radius: 40rpx;
  
  .send-text {
    font-size: 28rpx;
    color: #999;
  }
  
  &.send-btn-active {
    background-color: #FFF27C;
    
    .send-text {
      color: #333;
    }
  }
}

.recording-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.recording-popup {
  width: 500rpx;
  height: 280rpx;
  background: linear-gradient(135deg, #95EC69 0%, #7FD65C 100%);
  border-radius: 20rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.2);
  margin-bottom: 100rpx;
  transition: all 0.3s ease;
  
  // 取消模式：变为红色
  &.recording-cancel {
    background: linear-gradient(135deg, #FF6B6B 0%, #EE5A6F 100%);
  }
  
  // 气泡尖角
  &::after {
    content: '';
    position: absolute;
    bottom: -20rpx;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 20rpx solid transparent;
    border-right: 20rpx solid transparent;
    border-top: 20rpx solid #7FD65C;
    transition: all 0.3s ease;
  }
  
  &.recording-cancel::after {
    border-top-color: #EE5A6F;
  }
}

.recording-wave-container {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6rpx;
  height: 100rpx;
}

.wave-bar {
  width: 6rpx;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 3rpx;
  animation: waveAnimation 1.2s ease-in-out infinite;
}

// 为每个波形条设置不同高度和延迟
.wave-bar-1 { height: 20rpx; animation-delay: 0s; }
.wave-bar-2 { height: 35rpx; animation-delay: 0.05s; }
.wave-bar-3 { height: 45rpx; animation-delay: 0.1s; }
.wave-bar-4 { height: 30rpx; animation-delay: 0.15s; }
.wave-bar-5 { height: 50rpx; animation-delay: 0.2s; }
.wave-bar-6 { height: 40rpx; animation-delay: 0.25s; }
.wave-bar-7 { height: 55rpx; animation-delay: 0.3s; }
.wave-bar-8 { height: 35rpx; animation-delay: 0.35s; }
.wave-bar-9 { height: 45rpx; animation-delay: 0.4s; }
.wave-bar-10 { height: 30rpx; animation-delay: 0.45s; }
.wave-bar-11 { height: 40rpx; animation-delay: 0.5s; }
.wave-bar-12 { height: 50rpx; animation-delay: 0.55s; }
.wave-bar-13 { height: 35rpx; animation-delay: 0.6s; }
.wave-bar-14 { height: 45rpx; animation-delay: 0.65s; }
.wave-bar-15 { height: 55rpx; animation-delay: 0.7s; }
.wave-bar-16 { height: 40rpx; animation-delay: 0.75s; }
.wave-bar-17 { height: 30rpx; animation-delay: 0.8s; }
.wave-bar-18 { height: 45rpx; animation-delay: 0.85s; }
.wave-bar-19 { height: 35rpx; animation-delay: 0.9s; }
.wave-bar-20 { height: 50rpx; animation-delay: 0.95s; }

@keyframes waveAnimation {
  0%, 100% {
    transform: scaleY(0.5);
  }
  50% {
    transform: scaleY(1);
  }
}

.recording-actions {
  position: absolute;
  bottom: 200rpx;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  justify-content: center;
}

.action-item {
  padding: 24rpx 60rpx;
  border-radius: 60rpx;
  background-color: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(10rpx);
  transition: all 0.3s ease;
  
  .action-text {
    font-size: 32rpx;
    color: rgba(255, 255, 255, 0.95);
    font-weight: 500;
  }
  
  // 取消模式激活状态
  &.cancel-active {
    background-color: rgba(255, 255, 255, 0.4);
    transform: scale(1.1);
  }
}

.release-tip {
  position: absolute;
  bottom: 80rpx;
  left: 50%;
  transform: translateX(-50%);
  
  .release-text {
    font-size: 32rpx;
    color: rgba(255, 255, 255, 0.95);
    font-weight: 500;
    letter-spacing: 2rpx;
  }
}
</style>
